package com.bibrApp.difu.fragment.receiver_mvp;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bibrApp.difu.BeemIntent;
import com.bibrApp.difu.DfApp;
import com.bibrApp.difu.R;
import com.bibrApp.difu.base.BaseFragment;
import com.bibrApp.difu.dialog.InputPinDialog;
import com.bibrApp.difu.fragment.send_mvp.ISendView;
import com.bibrApp.difu.fragment.send_mvp.SendAdapter;
import com.bibrApp.difu.fragment.send_mvp.SendBean;
import com.bibrApp.difu.fragment.send_mvp.SendFragment;
import com.bibrApp.difu.fragment.send_mvp.SendPresenter;
import com.bibrApp.difu.proto2javabean.WalletAssetBean;
import com.bibrApp.difu.utils.ClsPublicUtils;
import com.bibrApp.difu.utils.DialogUtils;
import com.bibrApp.difu.utils.Protocol;
import com.bibrApp.difu.utils.SystemClipboardUtils;
import com.bibrApp.difu.utils.ToastUtils;
import com.bibrApp.difu.utils.UCaculateUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import com.googlecode.protobuf.format.JsonFormat;
import com.satoshilabs.trezor.lib.protobuf.TrezorMessageBitcoin;
import com.satoshilabs.trezor.lib.protobuf.TrezorMessageCommon;
import com.satoshilabs.trezor.lib.protobuf.TrezorMessageEthereum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

public class ReceiverFragment extends BaseFragment<ReceiverPresenter> implements IReceiverView {

    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;
    @BindView(R.id.tv_old_addr)
    TextView tv_old_addr;
    private ReceiverAdapter adapter;
    private UsbManager usbManager;//usb管理器
    private UsbDevice mUsbDevice;//找到的usb设备
    private UsbInterface mUsbInterface;
    private UsbDeviceConnection mUsbDeviceConnection;
    private Context mContext;

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_receiver;
    }

    @Override
    protected void initPresenter() {
        presenter = new ReceiverPresenter(getContext(), this);
        presenter.init();
    }

    @Override
    public void error(String msg) {

    }
    @OnClick(R.id.tv_old_copy)
    public void copyClick(){
        String oldAddress = tv_old_addr.getText().toString();
        if(!TextUtils.isEmpty(oldAddress)){
            SystemClipboardUtils.copyToClipboard(oldAddress,mContext);
            ToastUtils.ShowToast(mContext,"旧地址复制成功");
        }else{
            ToastUtils.ShowToast(mContext,"旧地址为空");

        }
    }
    @Override
    public void successOfGetAssets(WalletAssetBean walletAssetBean) {
        if(walletAssetBean != null && walletAssetBean.getTokens() != null && walletAssetBean.getTokens().size() >0){
            tv_old_addr.setText(walletAssetBean.getTokens().get(0).getName());
        }
    }

    @Override
    public void initView() {
        mContext = getContext();
        usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        adapter = new ReceiverAdapter();
        recyclerView.setAdapter(adapter);
        adapter.setOnItemChildClickListener((adapter1, view, position) -> {
            if (view.getId() == R.id.tv_old_copy) {
                String address = adapter.getItem(position);
                if(!TextUtils.isEmpty(address)){
                    SystemClipboardUtils.copyToClipboard(address,mContext);
                    ToastUtils.ShowToast(mContext,"复制成功");
                }else{
                    ToastUtils.ShowToast(mContext,"地址为空");
                }


            }
        });
        checkUsb();
        DfApp dfApp = (DfApp)getActivity().getApplication();
        presenter.getBtcBlance("btc",dfApp.getXpub());
    }

    private void checkUsb() {
        if (usbManager == null) {
            return;
        }
        HashMap<String, UsbDevice> deviceHashMap = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceHashMap.values().iterator();
        ArrayList<String> usbDeviceList = new ArrayList<>();//存放usb数量
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            usbDeviceList.add(String.valueOf(device.getVendorId()));
            usbDeviceList.add(String.valueOf(device.getProductId()));
            if (device.getVendorId() == 0x1209 && device.getProductId() == 0x53C1) {//找到我们的usb设备
                ToastUtils.ShowToast(mContext, "找到了对应的usb设备（硬件钱包）");
                mUsbDevice = device;
            }
        }
        //请求权限
        if (mUsbDevice == null) {
            ToastUtils.ShowToast(mContext, "没找到对应的usb设备");
            return;
        }
        if (usbManager.hasPermission(mUsbDevice)) {
            findIntfAndEpt();
        } else {
            getUsbPermission(mUsbDevice);
        }
    }

    /**
     * 寻找接口和分配结点
     */
    private UsbEndpoint usbEndpointIn;
    private UsbEndpoint usbEndpointOut;

    private void findIntfAndEpt() {
        if (mUsbDevice == null) {
            return;
        }
        if (mUsbDevice.getInterfaceCount() <= 0) {
            return;
        }
        mUsbInterface = mUsbDevice.getInterface(0);
        //打开设备，获取UsbDeviceConnection对象，连接设备，用于后面的通讯
        UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(mUsbDevice);
        if (usbDeviceConnection == null) {
            return;
        }
        if (usbDeviceConnection.claimInterface(mUsbInterface, true)) {
            //找到接口
            mUsbDeviceConnection = usbDeviceConnection;
            //用于UsbDeviceConnection与UsbInterface进行端点设置和通讯
            if (mUsbInterface.getEndpoint(0) != null) {
                usbEndpointIn = mUsbInterface.getEndpoint(0);
            }
            if (mUsbInterface.getEndpoint(1) != null) {
                usbEndpointOut = mUsbInterface.getEndpoint(1);
            }
            sendMsg2Device(0);
        } else {
            //断开连接
            usbDeviceConnection.close();
        }
    }
    /**
     * 给u盾发送数据
     */
    private void sendMsg2Device(int num) {
        int ret = -100;
        TrezorMessageBitcoin.GetAddress.Builder getAddressBuilder = TrezorMessageBitcoin.GetAddress.newBuilder();
        getAddressBuilder.setScriptType(TrezorMessageBitcoin.InputScriptType.SPENDP2SHWITNESS);
        List<Integer> address = new ArrayList<>(3);
        address.add(UCaculateUtils.changeNum(44));
        address.add(UCaculateUtils.changeNum(0));
        address.add(UCaculateUtils.changeNum(0));
        address.add(0);
        address.add(num);
        getAddressBuilder.addAllAddressN(address);
        TrezorMessageBitcoin.GetAddress signTx = getAddressBuilder.build();

        byte[] init = signTx.toByteArray();//转成16进制

        if (mUsbDeviceConnection == null) {
            ToastUtils.ShowToast(mContext, "没有建立连接");
            return;
        }
        //添加协议 getAddress = 29
        List<byte[]> bytes = Protocol.encode(29, init);
        // 1,发送准备命令
        //通过usb hid传输数据给u盾
        for (int i = 0; i < bytes.size(); i++) {
            byte[] sendbytes = bytes.get(i);
            ToastUtils.ShowToast(mContext, "发送的数据：" + ClsPublicUtils.bytesToHex(sendbytes));
            Log.d("dj", "==发送数据==" + ClsPublicUtils.bytesToHex(sendbytes));
            mUsbDeviceConnection.bulkTransfer(usbEndpointOut, sendbytes, sendbytes.length, 5000);
        }
        getHidMsg();
    }
    /**
     * 获取u盾的消息
     */
    @SuppressLint("StaticFieldLeak")
    public void getHidMsg() {
        new AsyncTask<String, Integer, List<byte[]>>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                //开始接受信息
                DialogUtils.showDialog(mContext);
            }

            @Override
            protected List<byte[]> doInBackground(String... params) {
                List<byte[]> byteRe = new ArrayList<>();
                try {
                    boolean isContinue = true;
                    while (isContinue) {
                        byte[] recByte = new byte[64];
                        mUsbDeviceConnection.bulkTransfer(usbEndpointIn, recByte, recByte.length, 10000);
                       /* getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ToastUtils.ShowToast(mContext, "====解码：===" + ClsPublicUtils.bytesToHex(recByte));
                            }
                        });*/
                        if (Protocol.hasHead(recByte)) {
                            byteRe.add(recByte);
                        } else {
                            isContinue = false;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
               /* getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ToastUtils.ShowToast(mContext, "====解码数组大小：===" + byteRe.size());
                    }
                });*/
                return byteRe;
            }

            @SuppressLint("NewApi")
            @Override
            protected void onPostExecute(List<byte[]> bytes) {
                if (bytes == null || bytes.size() == 0) {
                    //接受信息失败
                    DialogUtils.dismissDialog();
                    return;
                }
                DialogUtils.dismissDialog();
                Log.d("dj","==解码=前="+ ClsPublicUtils.bytesToHex(bytes.get(0)));
                Log.d("dj","==解码=后="+Protocol.decode(bytes));
                try {
                    if(Protocol.getType(bytes) == 3){//失败
                        TrezorMessageCommon.Failure failure = TrezorMessageCommon.Failure.parseFrom(ClsPublicUtils.hexToBytes(Protocol.decode(bytes)));
                        ToastUtils.ShowToast(mContext,  failure.getMessage());
                    }else if(Protocol.getType(bytes) == 18){//需要输入pin码
                        showPinDialog();
                    } else if(Protocol.getType(bytes) == 30){//Address
                        TrezorMessageBitcoin.Address address = TrezorMessageBitcoin.Address.parseFrom(ClsPublicUtils.hexToBytes(Protocol.decode(bytes)));
                        String addressJson = JsonFormat.printToString(address);
//                        presenter.getBtcBlance(coinType.toLowerCase() ,"ypub6X8sy1kK2MTcg8149iBYFKd9bfoLeLt1MnxQF7BzqWVqez2BVb7pRLVoiRENduwp2vJmMFnXruYQ8xc3XRgLrGToTtkMEC51yw8yeVtY5jR");
                        Log.d("dj","==public=key=json="+addressJson);
                        Log.d("dj","==public=key=="+address);
                        adapter.addData(address.getAddress());
                    }else if(Protocol.getType(bytes) == 57){//获取eth地址成功
                        TrezorMessageEthereum.EthereumAddress ethereumAddress = TrezorMessageEthereum.EthereumAddress.parseFrom(ClsPublicUtils.hexToBytes(Protocol.decode(bytes)));
                        String ethereumAddressJson = JsonFormat.printToString(ethereumAddress);
                    }

                } catch (InvalidProtocolBufferException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }.execute();
    }


    /**
     * 弹出输入pin码的弹窗
     */
    private InputPinDialog.Builder mDialog;
    private void showPinDialog() {
        if(mDialog == null){
            mDialog = new InputPinDialog.Builder(mContext, R.style.OrderDialogStyle);
        }
        mDialog.setOnSureBtnClick(new InputPinDialog.OnSureBtnClick() {
            @Override
            public void onClickSure(String numTV) {
                sendPin(numTV);
                mDialog.dismiss();
            }
        });
        Log.d("dj","请输入pin码");
        mDialog.creater().show();
    }

    /**
     * 发送pin给u盾
     */
    private void sendPin(String numTV) {
        TrezorMessageCommon.PinMatrixAck.Builder pinMatrixAckBuilder =  TrezorMessageCommon.PinMatrixAck.newBuilder();
        pinMatrixAckBuilder.setPin(numTV);
        TrezorMessageCommon.PinMatrixAck pinMatrixAck = pinMatrixAckBuilder.build();//组装成对应的protobuf文件中的方法
        Log.d("dj","===publickeyjson==="+JsonFormat.printToString(pinMatrixAck));
        byte[] init = pinMatrixAck.toByteArray();//转成16进制

        if (mUsbDeviceConnection == null) {
            ToastUtils.ShowToast(mContext, "没有建立连接");
            return;
        }

        //添加协议 19 发送pin码
        List<byte[]> bytes = Protocol.encode(19, pinMatrixAck.toByteArray());
        // 1,发送准备命令
        //通过usb hid传输数据给u盾
        for (int i = 0; i < bytes.size(); i++) {
            byte[] sendbytes = bytes.get(i);
            Log.d("dj","==发送数据=="+ClsPublicUtils.bytesToHex(sendbytes));
            mUsbDeviceConnection.bulkTransfer(usbEndpointOut, sendbytes, sendbytes.length, 5000);
        }
        getHidMsg();
    }
    int num = 0;
    @OnClick(R.id.btn_add)
    public void addClick() {
        sendMsg2Device(++num);
    }

    private Receiver mUsbReceiver;
    //开始申请USB权限
    private void getUsbPermission(UsbDevice mUSBDevice) {
        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(BeemIntent.ACTION_USB_INTENT), 0);
        IntentFilter filter = new IntentFilter(BeemIntent.ACTION_USB_INTENT);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        mUsbReceiver = new Receiver();
        mContext.registerReceiver(mUsbReceiver, filter);
        usbManager.requestPermission(mUSBDevice, pendingIntent); // 该代码执行后，系统弹出一个对话框/等待权限
    }

    private class  Receiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BeemIntent.ACTION_USB_INTENT.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
                            && mUsbDevice.equals(device)) {
                        //TODO 授权成功，操作USB设备
                        ToastUtils.ShowToast(mContext, "usb授权成功");
                    } else {
                        //用户点击拒绝了
                        ToastUtils.ShowToast(mContext, "拒绝usb授权");
                    }
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mUsbReceiver != null) {
            mContext.unregisterReceiver(mUsbReceiver);
        }
    }

}
